"""
系统管理服务
创建时间：2025-09-17
作者：开发团队
目的：处理系统管理相关业务逻辑
"""

from sqlalchemy.orm import Session
from sqlalchemy import and_, desc
from ..models.user import User
from ..models.campus import Campus
from ..utils.logger import get_logger

# 获取日志记录器
logger = get_logger(__name__)


def get_admins(
    db: Session,
    skip: int = 0,
    limit: int = 100,
    campus_id: int | None = None,
    status: str | None = None
) -> list[User]:
    """
    获取管理员列表
    :param db: 数据库会话
    :param skip: 跳过的记录数
    :param limit: 返回的记录数
    :param campus_id: 院区ID筛选
    :param status: 状态筛选
    :return: 管理员列表
    """
    try:
        query = db.query(User).filter(User.role == "admin")
        
        # 添加筛选条件
        if campus_id:
            query = query.filter(User.campus_id == campus_id)
        if status:
            query = query.filter(User.status == status)
            
        # 按创建时间倒序排列
        admins = query.order_by(desc(User.created_at)).offset(skip).limit(limit).all()
        logger.info(f"获取管理员列表: {len(admins)} 条记录")
        return admins
    except Exception as e:
        logger.error(f"获取管理员列表失败: {str(e)}")
        raise


def create_admin(
    db: Session,
    username: str,
    password_hash: str,
    name: str,
    phone: str | None,
    campus_id: int | None
) -> User:
    """
    创建管理员账号
    :param db: 数据库会话
    :param username: 用户名
    :param password_hash: 密码哈希
    :param name: 姓名
    :param phone: 手机号
    :param campus_id: 院区ID
    :return: 创建的管理员账号
    """
    try:
        # 检查用户名是否已存在
        existing_user = db.query(User).filter(User.username == username).first()
        if existing_user:
            raise ValueError("用户名已存在")
        
        admin = User(
            username=username,
            password_hash=password_hash,
            name=name,
            role="admin",
            phone=phone,
            campus_id=campus_id,
            status="active"
        )
        db.add(admin)
        db.commit()
        db.refresh(admin)
        logger.info(f"创建管理员账号: username={username}")
        return admin
    except ValueError:
        db.rollback()
        raise
    except Exception as e:
        db.rollback()
        logger.error(f"创建管理员账号失败: {str(e)}")
        raise


def update_admin(
    db: Session,
    admin_id: int,
    name: str | None = None,
    phone: str | None = None,
    campus_id: int | None = None,
    status: str | None = None
) -> User | None:
    """
    更新管理员信息
    :param db: 数据库会话
    :param admin_id: 管理员ID
    :param name: 姓名
    :param phone: 手机号
    :param campus_id: 院区ID
    :param status: 状态
    :return: 更新后的管理员信息或None
    """
    try:
        admin = db.query(User).filter(and_(User.id == admin_id, User.role == "admin")).first()
        if not admin:
            return None
            
        if name is not None:
            setattr(admin, 'name', name)
        if phone is not None:
            setattr(admin, 'phone', phone)
        if campus_id is not None:
            setattr(admin, 'campus_id', campus_id)
        if status is not None:
            setattr(admin, 'status', status)
            
        db.commit()
        db.refresh(admin)
        logger.info(f"更新管理员信息: id={admin_id}")
        return admin
    except Exception as e:
        db.rollback()
        logger.error(f"更新管理员信息失败: {str(e)}")
        raise


def delete_admin(db: Session, admin_id: int) -> bool:
    """
    删除管理员账号
    :param db: 数据库会话
    :param admin_id: 管理员ID
    :return: 删除是否成功
    """
    try:
        admin = db.query(User).filter(and_(User.id == admin_id, User.role == "admin")).first()
        if admin:
            db.delete(admin)
            db.commit()
            logger.info(f"删除管理员账号: id={admin_id}")
            return True
        return False
    except Exception as e:
        db.rollback()
        logger.error(f"删除管理员账号失败: {str(e)}")
        raise


def get_campuses(
    db: Session,
    skip: int = 0,
    limit: int = 100
) -> list[Campus]:
    """
    获取院区列表
    :param db: 数据库会话
    :param skip: 跳过的记录数
    :param limit: 返回的记录数
    :return: 院区列表
    """
    try:
        campuses = db.query(Campus).order_by(desc(Campus.created_at)).offset(skip).limit(limit).all()
        logger.info(f"获取院区列表: {len(campuses)} 条记录")
        return campuses
    except Exception as e:
        logger.error(f"获取院区列表失败: {str(e)}")
        raise


def create_campus(
    db: Session,
    name: str,
    address: str,
    contact_person: str,
    contact_phone: str
) -> Campus:
    """
    创建院区
    :param db: 数据库会话
    :param name: 院区名称
    :param address: 地址
    :param contact_person: 联系人
    :param contact_phone: 联系电话
    :return: 创建的院区
    """
    try:
        # 检查院区名称是否已存在
        existing_campus = db.query(Campus).filter(Campus.name == name).first()
        if existing_campus:
            raise ValueError("院区名称已存在")
        
        # 创建新的院区对象，让数据库处理created_at和updated_at的默认值
        campus = Campus(
            name=name,
            address=address or None,  # 确保空字符串转换为None
            contact_person=contact_person or None,
            contact_phone=contact_phone or None
        )
        db.add(campus)
        db.commit()
        db.refresh(campus)
        logger.info(f"创建院区: name={name}, id={campus.id}")
        return campus
    except ValueError:
        db.rollback()
        raise
    except Exception as e:
        db.rollback()
        logger.error(f"创建院区失败: {str(e)}", exc_info=True)
        raise


def update_campus(
    db: Session,
    campus_id: int,
    name: str | None = None,
    address: str | None = None,
    contact_person: str | None = None,
    contact_phone: str | None = None
) -> Campus | None:
    """
    更新院区信息
    :param db: 数据库会话
    :param campus_id: 院区ID
    :param name: 院区名称
    :param address: 地址
    :param contact_person: 联系人
    :param contact_phone: 联系电话
    :return: 更新后的院区信息或None
    """
    try:
        campus = db.query(Campus).filter(Campus.id == campus_id).first()
        if not campus:
            return None
            
        if name is not None:
            # 检查院区名称是否已存在（排除当前院区）
            existing_campus = db.query(Campus).filter(and_(Campus.name == name, Campus.id != campus_id)).first()
            if existing_campus:
                raise ValueError("院区名称已存在")
            setattr(campus, 'name', name)
        if address is not None:
            # 确保空字符串转换为None
            setattr(campus, 'address', address if address else None)
        if contact_person is not None:
            # 确保空字符串转换为None
            setattr(campus, 'contact_person', contact_person if contact_person else None)
        if contact_phone is not None:
            # 确保空字符串转换为None
            setattr(campus, 'contact_phone', contact_phone if contact_phone else None)
            
        db.commit()
        db.refresh(campus)
        logger.info(f"更新院区信息: id={campus_id}")
        return campus
    except ValueError:
        db.rollback()
        raise
    except Exception as e:
        db.rollback()
        logger.error(f"更新院区信息失败: {str(e)}", exc_info=True)
        raise


def delete_campus(db: Session, campus_id: int) -> bool:
    """
    删除院区
    :param db: 数据库会话
    :param campus_id: 院区ID
    :return: 删除是否成功
    """
    try:
        campus = db.query(Campus).filter(Campus.id == campus_id).first()
        if campus:
            # 检查是否有用户关联到此院区
            user_count = db.query(User).filter(User.campus_id == campus_id).count()
            if user_count > 0:
                raise ValueError("该院校区有关联用户，无法删除")
            
            db.delete(campus)
            db.commit()
            logger.info(f"删除院区: id={campus_id}")
            return True
        return False
    except ValueError:
        db.rollback()
        raise
    except Exception as e:
        db.rollback()
        logger.error(f"删除院区失败: {str(e)}")
        raise


def get_admin_count(
    db: Session,
    campus_id: int | None = None,
    status: str | None = None
) -> int:
    """
    获取管理员总数
    :param db: 数据库会话
    :param campus_id: 院区ID筛选
    :param status: 状态筛选
    :return: 管理员总数
    """
    try:
        query = db.query(User).filter(User.role == "admin")
        
        # 添加筛选条件
        if campus_id:
            query = query.filter(User.campus_id == campus_id)
        if status:
            query = query.filter(User.status == status)
            
        count = query.count()
        logger.info(f"获取管理员总数: {count}")
        return count
    except Exception as e:
        logger.error(f"获取管理员总数失败: {str(e)}")
        raise


def get_campus_count(db: Session) -> int:
    """
    获取院区总数
    :param db: 数据库会话
    :return: 院区总数
    """
    try:
        count = db.query(Campus).count()
        logger.info(f"获取院区总数: {count}")
        return count
    except Exception as e:
        logger.error(f"获取院区总数失败: {str(e)}")
        raise